From 141ba5cf73029029a5a0bd2cdcfd5f9f9ab7ee7b Mon Sep 17 00:00:00 2001
From: Kai Krakow <kai@kaishome.de>
Date: Thu, 4 Oct 2018 05:51:20 +0200
Subject: [PATCH] winex11.drv: Bypass compositor in fullscreen mode

Bypass the compositor in fullscreen mode. This reduces stutter
introduced by window updates in the background and also allows for maybe
a few more FPS. To not change the visual appearance of the desktop for
windowed games, this hack only enables itself when the game was switched
to fullscreen mode, and returns to default WM setting when the game
leaves fullscreen mode.

Compositors tend to cause severe stutter if the game is GPU-bound.
---
 dlls/winex11.drv/window.c      | 8 +++++++
 dlls/winex11.drv/x11drv.h      | 1 +
 dlls/winex11.drv/x11drv_main.c | 1 +
 3 files changed, 9 insertions(+)

diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 8256749a8d..ec29e875d2 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -985,6 +985,7 @@ void update_user_time( Time time )
 void update_net_wm_states( struct x11drv_win_data *data )
 {
     DWORD i, style, ex_style, new_state = 0;
+    unsigned long net_wm_bypass_compositor = 0;
 
     if (!data->managed) return;
     if (data->whole_window == root_window) return;
@@ -997,7 +998,10 @@ void update_net_wm_states( struct x11drv_win_data *data )
         if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
             new_state |= (1 << NET_WM_STATE_MAXIMIZED);
         else if (!(style & WS_MINIMIZE))
+	{
+            net_wm_bypass_compositor = 1;
             new_state |= (1 << NET_WM_STATE_FULLSCREEN);
+	}
     }
     else if (style & WS_MAXIMIZE)
         new_state |= (1 << NET_WM_STATE_MAXIMIZED);
@@ -1064,6 +1068,10 @@ void update_net_wm_states( struct x11drv_win_data *data )
         }
     }
     data->net_wm_state = new_state;
+
+    XChangeProperty( data->display, data->whole_window, x11drv_atom(_NET_WM_BYPASS_COMPOSITOR), XA_CARDINAL,
+                     32, PropModeReplace, (unsigned char *)&net_wm_bypass_compositor, 1 );
+
 }
 
 /***********************************************************************
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index ccdb6c6efa..9aa41a80b7 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -444,6 +444,7 @@ enum x11drv_atoms
     XATOM__NET_SYSTEM_TRAY_OPCODE,
     XATOM__NET_SYSTEM_TRAY_S0,
     XATOM__NET_SYSTEM_TRAY_VISUAL,
+    XATOM__NET_WM_BYPASS_COMPOSITOR,
     XATOM__NET_WM_ICON,
     XATOM__NET_WM_MOVERESIZE,
     XATOM__NET_WM_NAME,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 7a7ce335c7..2b11bba229 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -135,6 +135,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
     "_NET_SYSTEM_TRAY_OPCODE",
     "_NET_SYSTEM_TRAY_S0",
     "_NET_SYSTEM_TRAY_VISUAL",
+    "_NET_WM_BYPASS_COMPOSITOR",
     "_NET_WM_ICON",
     "_NET_WM_MOVERESIZE",
     "_NET_WM_NAME",
